<template>

  <div>
    <Layout>
      <Content class="layout-content">

        <Row>

          <Col span="2">
            <Button type="primary" @click="genneratorTemplate">生成模版</Button>
          </Col>

          <Col span="2">
            <Button type="primary" @click="registerLevelMappingOpen">挂号级别映射</Button>

            <Modal
                v-model="registerLevelMappingFlag"
                title="请输入映射关系"
                :mask-closable="false"
                @on-ok="registerLevelMapping"
                @on-cancel="registerLevelMappingFlag=false">
              <div id="registerLevelMappingEditor"
                   style="width: 100%; height: 600px;"></div>
            </Modal>

          </Col>

          <Col span="4">
            <input type="file" style="display: none;" accept=".xlsx" ref="fileUpload" @change="fileChange"/>
            <Button type="primary" @click="importApp">导入数据</Button>
          </Col>

          <Col span="4">
            <DatePicker type="date" v-model="startDate" placeholder="Select date"/>
          </Col>

          <Col span="2">
            <Button type="primary" @click="importAppConfirm">确认导入</Button>
          </Col>

          <Col span="2">
            <Checkbox v-model="submitScheduleFlag">提交排班</Checkbox>
          </Col>


          <Col span="2">
            日志:
            <Switch v-model="logViewFlag"/>
          </Col>
        </Row>
        <Row>

          <Col span="24">
          </Col>
        </Row>


        <Row>

          <Col span="24">
            <Drawer title="日志查看" :mask="false" :closable="true" :width="600" :z-index="9999" :draggable="true"
                    v-model="logViewFlag">
              <LogView></LogView>
            </Drawer>
          </Col>
        </Row>


        <Row>

          <Col span="24">
            <SheetView ref="sonDataRef"/>
          </Col>
        </Row>

      </Content>
    </Layout>


    <Modal
        v-model="showJsonView"
        title="Common Modal dialog box title"
        @on-ok="showJsonView=false"
        @on-cancel="showJsonView=false">
      <div id="jsoneditor" ref="jsonEditor" style="width: 100%; height: 600px;"></div>
    </Modal>

  </div>
</template>
<script setup>
import {onMounted, ref, toRaw, inject, getCurrentInstance, provide} from "vue";
import api from '../request/apis'
import moment from "moment";
import {Col, DatePicker, Message} from 'view-ui-plus'
import {nextTick, debounce} from '../utils'
import _ from "lodash";
import * as XLSX from "xlsx";
import * as ExcelJS from "exceljs";
import {importAppointment} from "./AppointmentImport.js";
import LogView from "./logview/LogView.vue";
import {appointmentInject} from "./AppointmentInject.js";
import SheetView from "./SheetView.vue";
import {clear, info} from "./logview/index.js";
import JsonEditor from 'jsoneditor';
import 'jsoneditor/dist/jsoneditor.min.css';

const fileUpload = ref();
const showJsonView = ref(false);

const logViewFlag = ref(false);
const importApp = () => {
  fileUpload.value.click();

}

// const startDate= ref();
const startDate = ref(new Date(moment().add(7, 'days')
    .startOf('week').add(1, 'day').format("YYYY-MM-DD")));


const wseditor = ref();

const initJsonEditor = () => {
  const container = document.getElementById("jsoneditor");

  const options = {
    "modes": ["code", "tree", "form", "text", "preview"],
    "mode": "code"
  }
  wseditor.value = new JsonEditor(container, options);
  // const initJson = {};
  // editor.value.set(initJson);
}

const regEditor = ref();
const registerLevelMappingFlag = ref(false);
const registerLevelMapping = () => {
  registerLevelMappingFlag.value = false;
  let c = null;
  try {
    c = regEditor.value.get();
  } catch (e) {

  }
  if (c) {
    localStorage.setItem("registerLevelMapping", JSON.stringify(c));
  } else {
    localStorage.removeItem("registerLevelMapping");
  }

}

const registerLevelMappingOpen = async () => {
  registerLevelMappingFlag.value = true;
  if (!regEditor.value) {
    initEditor();
  }

  const c = localStorage.getItem("registerLevelMapping");
  if (c) {
    regEditor.value.set(JSON.parse(c));
  } else {

    const registerCategoryList = await api.queryRegisterCategoryList();
    const ms = [];
    for (const registerCategory of registerCategoryList) {
      ms.push(registerCategory.code);
    }
    const registerLevelList = await api.queryRegisterLevelList(ms);
    const result = [];
    for (const c of registerLevelList) {
      result.push({
        sourceName: [c.name],
        targetName: c.name
      })
    }
    regEditor.value.set(result);
  }
}
const initEditor = () => {
  const container = document.getElementById("registerLevelMappingEditor");

  const options = {
    "modes": ["code", "tree", "form", "text", "preview"],
    "mode": "code"
  }
  regEditor.value = new JsonEditor(container, options);
}

const submitScheduleFlag = ref(false);

const deptMap = ref();
const fileChange = async (e) => {
  const file = e.target.files[0];
  e.target.value = null;
  logViewFlag.value = true;

  const fileFr = new FileReader();

  fileFr.readAsArrayBuffer(file);


  fileFr.onload = async (e) => {
    // 文件的ArrayBuffer结果
    // const buffer = Buffer.from();
    try {
      sonDataRef.value.callBack(e.target.result, file.name);
    } catch (e) {

    }
    // 从文件读取
    const workbook = new ExcelJS.Workbook();
    await workbook.xlsx.load(e.target.result);
    const resultMap = new Map();
    workbook.eachSheet(function (worksheet, sheetId) {
      //这是科室
      // console.log(worksheet, sheetId);
      const deptNameStr = worksheet.name;
      //
      const deptId = deptNameStr.split("-")[1];
      const deptName = deptNameStr.split("-")[0];
      const doctorList = [];
      resultMap.set(deptId, doctorList);
      worksheet.eachRow(function (row, rowNumber) {
        // console.log(row)
        // console.log(rowNumber)
        if (rowNumber != 1) {
          const rowJson = {
            deptId: deptId,
            deptName: deptName,
          }
          row.eachCell(function (cell, colNumber) {
            if (cell.address.indexOf("A") != -1) {
              const doctorInfo = cell.value;
              const doctorId = doctorInfo.split("-")[1];
              const doctorName = doctorInfo.split("-")[0];
              rowJson.doctorId = doctorId;
              rowJson.doctorName = doctorName;
            } else if (cell.address.indexOf("B") != -1) {
              const addressInfo = cell.value;
              rowJson.locationName = addressInfo;
            } else if (cell.address.indexOf("C") != -1) {
              let registerCategoryName = cell.value;
              if (typeof registerCategoryName == 'object') {
                registerCategoryName = registerCategoryName.richText[0].text;
              }

              rowJson.registerCategoryName = registerCategoryName;
            } else if (cell.address.indexOf("D") != -1) {
              let registerLevelName = cell.value;
              if (typeof registerLevelName == 'object') {
                registerLevelName = registerLevelName.richText[0].text;
              }
              rowJson.registerLevelName = registerLevelName;
            } else if (cell.address.indexOf("E") != -1) {
              const shiftName = cell.value;
              rowJson.shiftName = shiftName;
            } else if (cell.address.indexOf("F") != -1) {
              const day1 = cell.value;
              rowJson.day1 = day1;
            } else if (cell.address.indexOf("G") != -1) {
              const day2 = cell.value;
              rowJson.day2 = day2;
            } else if (cell.address.indexOf("H") != -1) {
              const day3 = cell.value;
              rowJson.day3 = day3;
            } else if (cell.address.indexOf("I") != -1) {
              const day4 = cell.value;
              rowJson.day4 = day4;
            } else if (cell.address.indexOf("J") != -1) {
              const day5 = cell.value;
              rowJson.day5 = day5;
            } else if (cell.address.indexOf("K") != -1) {
              const day6 = cell.value;
              rowJson.day6 = day6;
            } else if (cell.address.indexOf("L") != -1) {
              const day7 = cell.value;
              rowJson.day7 = day7;
            }
          });
          if (rowJson.day1 || rowJson.day2 || rowJson.day3 || rowJson.day4 || rowJson.day5 || rowJson.day6
              || rowJson.day7) {
            doctorList.push(rowJson);
          }
        }
      });
    });

    clear();

    //这里还要对对象设置班次
    deptMap.value = [];
    deptMap.value = await appointmentInject(resultMap, moment(startDate.value).format("YYYY-MM-DD") + " 00:00:00");
    let uploadRow = [];
    for (const c of toRaw(deptMap.value)) {
      if (c[1].length > 0) {
        for (const cb of c[1]) {
          uploadRow.push(cb);
        }
      }
    }
    showJsonView.value = true;
    if (!wseditor.value) {
      initJsonEditor();
    }

    wseditor.value.set(uploadRow);

    // alert(JSON.stringify(uploadRow));
    // await importAppointment(deptMap, toRaw(submitScheduleFlag.value));
  }
}

const importAppConfirm = async () => {
  await importAppointment(toRaw(deptMap.value), toRaw(submitScheduleFlag.value), moment(startDate.value).format("YYYY-MM-DD") + " 00:00:00");
}

const workbook2blob = async (workbook) => {
  // 生成excel的配置项
  const buffer = await workbook.xlsx.writeBuffer();
  var blob = new Blob([buffer], {
    type: 'application/octet-stream'
  })
  return blob
}

// 将blob对象 创建bloburl,然后用a标签实现弹出下载框
const openDownloadDialog = (blob, fileName) => {
  if (typeof blob === 'object' && blob instanceof Blob) {
    blob = URL.createObjectURL(blob) // 创建blob地址
  }
  var aLink = document.createElement('a')
  aLink.href = blob
  // HTML5新增的属性，指定保存文件名，可以不要后缀，注意，有时候 file:///模式下不会生效
  aLink.download = fileName || ''
  var event
  if (window.MouseEvent) event = new MouseEvent('click')
  //   移动端
  else {
    event = document.createEvent('MouseEvents')
    event.initMouseEvent('click', true, false, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null)
  }
  aLink.dispatchEvent(event)
}

const sonDataRef = ref();
const exportExcel = async (deptList) => {

  const deptIds = [];
  for (const dept of deptList) {
    deptIds.push(dept.id);
  }
  let doctorResultList = await api.listDoctorByDeptIds(deptIds);
  //过滤挂号级别
  const doctorList = [];
  for (const doctor of doctorResultList) {
    let find = false;
    for (const qualification of doctor.qualificationList) {
      const code = qualification?.practiceType?.code;
      if (code && code == 'GB/T8561.230') {
        find = true;
      }
    }
    if (find) {
      doctorList.push(doctor);
    }
  }
  const locationList = await api.listLocationByType(deptIds);

  const registerCategoryList = await api.queryRegisterCategoryList();
  const ms = [];
  for (const registerCategory of registerCategoryList) {
    ms.push(registerCategory.code);
  }
  const registerLevelList = await api.queryRegisterLevelList(ms);

  // 创建一个新的空的workbook
  for (const dept of deptList) {
    let deptName = dept.name;
    // \ / ? * [ ]
    deptName = deptName.replace(/\\/g, "");
    deptName = deptName.replace(/\//g, "");
    deptName = deptName.replace(/\?/g, "");
    deptName = deptName.replace(/\*/g, "");
    deptName = deptName.replace(/\[/g, "");
    deptName = deptName.replace(/]/g, "");
    deptName = `${deptName}-${dept.id}`;
    dept.name = deptName;
    const doctorResult = findDoctorList(dept.id, doctorList);
    dept.doctorList = doctorResult;

    const locations = findLocationList(dept.id, locationList);
    dept.locationList = locations;

  }
  const workbook = new ExcelJS.Workbook();
  workbook.creator = 'gydfy';
  workbook.lastModifiedBy = 'gydfy';
  workbook.created = new Date();
  workbook.modified = new Date();
  workbook.lastPrinted = new Date();
// 将工作簿日期设置为 1904 年日期系统
  workbook.properties.date1904 = true;
  // 在加载时强制工作簿计算属性
  workbook.calcProperties.fullCalcOnLoad = true;
  //工作簿视图控制在查看工作簿时 Excel 将打开多少个单独的窗口。
  workbook.views = [
    {
      firstSheet: 0, activeTab: 0, visibility: 'visible'
    }
  ]
  for (const dept of deptList) {
    const sheet = workbook.addWorksheet(dept.name, {views: [{state: 'frozen', xSplit: 1, ySplit: 1}]});
    sheet.autoFilter = 'A1:L1';
    sheet.columns = [
      {header: '医生', key: '医生', width: 30},
      {header: '地址', key: '地址', width: 30},
      {header: '挂号类别', key: '挂号类别', width: 10},
      {header: '挂号级别', key: '挂号级别', width: 10},
      // {header: '加号限额', key: '加号限额', width: 10},
      // {header: '号源数', key: '号源数', width: 10},
      {header: '班次', key: '班次', width: 10},
      {header: '星期一', key: '星期', width: 10},
      {header: '星期二', key: '星期', width: 10},
      {header: '星期三', key: '星期', width: 10},
      {header: '星期四', key: '星期', width: 10},
      {header: '星期五', key: '星期', width: 10},
      {header: '星期六', key: '星期', width: 10},
      {header: '星期日', key: '星期', width: 10}
    ];
    addDoctorList(dept, sheet, registerCategoryList, registerLevelList);
  }
  //转blob
  const workbookBlob = await workbook2blob(workbook);

  const startDateStr = moment().format('YYYYMMDDHHMMSS');
  // wbb.value = workbookBlob;
  const fileName = `排班excel模版${startDateStr}.xlsx`;

  // provide('workbookBlob', wbb);
  // provide('fileName', fileName);
  try {
    sonDataRef.value.callBack(workbookBlob, fileName);
  } catch (e) {

  }
  //下载
  openDownloadDialog(workbookBlob, fileName);
}
const shiftList = ['上午班', '下午班', '中午班', '晚班', '夜间班', '深夜班', '全天班'];

const addDoctorList = (dept, sheet, registerCategoryList, registerLevelList) => {
  const lcList = dept.locationList;
  let address = null;
  if (lcList.length == 1) {
    address = lcList[0].name;
  }
  let i = 1;
  for (const doctor of dept.doctorList) {
    if (doctor.accountNo.indexOf("gycs") != -1 || doctor.accountNo.indexOf("gyyf") != -1) {
      continue;
    }
    for (const shift of shiftList) {
      sheet.addRow({
        "医生": doctor.name + "-" + doctor.id + `（${doctor.accountNo}）`,//A
        "地址": address,//B
        "挂号类别": null,//C
        "挂号级别": null,//D
        "班次": shift,//E
        "星期一": null,//F
        "星期二": null,//G
        "星期三": null,//H
        "星期四": null,//I
        "星期五": null,//J
        "星期六": null,//K
        "星期日": null//L
      });
      let str = "";
      for (const location of lcList) {
        str += `${location.name},`;
      }
      //地址
      sheet.getCell('B' + (i + 1)).dataValidation = {
        type: 'list',
        allowBlank: true,
        formulae: [`"${str}"`]
      };

      let registerCategoryListStr = "";
      for (const registerCategory of registerCategoryList) {
        if (registerCategory.name == '急诊' || registerCategory.name == '专病' || registerCategory.name == '在线问诊普通'
            || registerCategory.name == '在线问诊专家') {
          continue;
        }
        registerCategoryListStr += `${registerCategory.name},`
      }
      //挂号类别
      sheet.getCell('C' + (i + 1)).dataValidation = {
        type: 'list',
        allowBlank: true,
        formulae: [`"${registerCategoryListStr}"`]
      };

      let sre = "";
      //挂号级别
      for (const qualification of doctor.qualificationList) {
        const code = qualification?.professionalTitle?.code;
        if (code && code.indexOf("GB/T8561") == -1) {
          continue;
        }
        for (const registerLevel of registerLevelList) {
          if (registerLevel?.appointmentResourceExtra?.doctorProfessionalCode == code) {

            //   let chargeItemList = registerLevel.chargeItemList;
            // var amount = 0.00;
            // if (chargeItemList && chargeItemList.length > 0) {
            //   for (const chargeItem of chargeItemList) {
            //     amount += chargeItem.price || 0.00;
            //   }
            // }
            sre = `${sre}${registerLevel.name},`;
          }
        }
      }
      //挂号级别
      sheet.getCell('D' + (i + 1)).dataValidation = {
        type: 'list',
        allowBlank: true,
        formulae: [`"${sre}"`]
      };


      // sheet.getCell('E' + (i + 1)).dataValidation = {
      //   type: 'whole',
      //   allowBlank: true,
      //   formulae: [1, 999],
      // };
      let shiftStr = "";
      for (const shift of shiftList) {
        shiftStr += `${shift},`
      }
      //班次
      sheet.getCell('E' + (i + 1)).dataValidation = {
        type: 'list',
        allowBlank: true,
        formulae: [`"${shiftStr}"`]
      };
      //F-L 星期
      const cs = ['F', 'G', 'H', 'I', 'J', 'K', 'L']
      for (const csb of cs) {
        sheet.getCell(csb + (i + 1)).dataValidation = {
          type: 'whole',
          allowBlank: true,
          formulae: [1, 999],
        };
      }
      i++;
    }
  }
}

const findLocationList = (deptId, locationList) => {

  const doctorListResult = [];
  for (const doctor of locationList) {

    if (!doctor.unitIds || doctor.unitIds.length <= 0) {
      continue;
    }
    let i = 0;
    for (const staffUnit of doctor.unitIds) {
      if (staffUnit == deptId) {
        i++;
      }
    }
    if (i > 0) {
      doctorListResult.push(doctor);
    }
  }
  return doctorListResult;

}
const findDoctorList = (deptId, doctorList) => {

  const doctorListResult = [];
  for (const doctor of doctorList) {

    if (!doctor.staffUnitList || doctor.staffUnitList.length <= 0) {
      continue;
    }
    let i = 0;
    for (const staffUnit of doctor.staffUnitList) {
      if (staffUnit.unitId == deptId) {
        i++;
      }
    }
    if (i > 0) {
      doctorListResult.push(doctor);
    }
  }
  return doctorListResult;
}

const genneratorTemplate = async () => {

  //这里需要查询所有排班科室
  let deptList = await api.queryAllOutpatientSchedule();
  //排一把序
  deptList = _.orderBy(deptList, ['sortNo'], ['asc']);
  await exportExcel(deptList);

}


//

</script>
<style scoped>
</style>